home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / WD_SRC.ZIP / BSP_GEN / IO.CPP < prev    next >
C/C++ Source or Header  |  1995-01-12  |  15KB  |  581 lines

  1. #include "..\Source\LastWolf.hpp"
  2.  
  3.  
  4. extern DWORD nSplits, nBalancesChosen, nSplitsChosen;
  5. extern WORD nOriginalPoints, nOriginalLines;
  6. extern WORD nExactIntersections;
  7.  
  8.  
  9.  
  10. BOOL ProcessCommandLine( int argc, char *argv[], BspCommandLine *pToProcess )
  11. {
  12.     if( argc < 4 )
  13.         return FALSE;
  14.  
  15.     pToProcess->bDoomLevel = FALSE;
  16.  
  17.     pToProcess->pFilename = argv[1];
  18.     pToProcess->pOutputFile = argv[2];
  19.  
  20.     pToProcess->balance = (WORD)atoi( argv[3] );
  21.  
  22.     if( argc >= 5 )
  23.     {
  24.         pToProcess->bDoomLevel = TRUE;
  25.         pToProcess->pLevelName = argv[4];
  26.             
  27.         if( argv[5][0] == '1' )
  28.         {
  29.             pToProcess->bLoadDoomTextures = FALSE;
  30.             pToProcess->pTextureWadName = NULL;
  31.         }
  32.         else
  33.         {
  34.             pToProcess->bLoadDoomTextures = TRUE;
  35.             pToProcess->pTextureWadName = argv[5];
  36.         }
  37.             
  38.         if( argc > 6 )
  39.             videoMode = atoi(argv[6]);
  40.     }
  41.  
  42.     return TRUE;
  43. }
  44.  
  45.  
  46. BOOL LoadTextData( BYTE *pFilename, CLineArray *pLines, CPointArray *pPoints )                                                                      
  47. {
  48.     FILE *fpText;
  49.     WORD nLines, nPoints;
  50.  
  51.     WORD curPoint, curLine;
  52.     
  53.     // Used when reading Lines in.
  54.     WORD iPoint1, iPoint2;
  55.     
  56.     CPoint  *pCurPoint;
  57.     CLine   *pCurLine;
  58.     
  59.     
  60.     fpText = fopen( pFilename, "r" );
  61.     if( fpText == NULL )
  62.         return FALSE;
  63.  
  64.     
  65.     // Get the number of Points and Lines.
  66.     SkipComments(fpText);
  67.     fscanf( fpText, "%hd", &nPoints );
  68.     SkipComments(fpText);
  69.     fscanf( fpText, "%hd", &nLines );
  70.  
  71.     // Allocate the memory for the arrays.
  72.     pLines->SetSize(nLines);
  73.     pPoints->SetSize(nPoints);
  74.     
  75.     pLines->AllocateElements();
  76.     pPoints->AllocateElements();
  77.     
  78.     // Read in all the Points.
  79.     for( curPoint=0; curPoint < nPoints; curPoint++ )
  80.     {
  81.         pCurPoint = pPoints->GetPoint(curPoint);
  82.  
  83.         SkipComments(fpText);
  84.         fscanf( fpText, "%hd , %hd", &pCurPoint->localX, &pCurPoint->localY );
  85.     }   
  86.     
  87.     
  88.     // Read in all the Lines.
  89.     for( curLine=0; curLine < nLines; curLine++ )
  90.     {
  91.         pCurLine = pLines->GetLine(curLine);
  92.         
  93.         SkipComments(fpText);
  94.         fscanf( fpText, "%hd , %hd", &iPoint1, &iPoint2 );
  95.         
  96.         pCurLine->pPoint1 = pPoints->GetPoint(iPoint1);
  97.         pCurLine->pPoint2 = pPoints->GetPoint(iPoint2);
  98.         
  99.         SkipComments(fpText);
  100.         fscanf( fpText, "%hd , %hd", &pCurLine->idLeftTex, &pCurLine->idRightTex );
  101.     }
  102.  
  103.     
  104.     fclose(fpText); 
  105.  
  106.     return TRUE;
  107. }
  108.  
  109.  
  110. BOOL OutputTextData( CLine *pRoot, char *pFilename, CLineArray *pLines, CPointArray *pPoints )
  111. {
  112.     CPoint  *pCurPoint;
  113.     CLine   *pCurLine;
  114.     Index i, iPoint1, iPoint2, iLeft, iRight;
  115.     WORD nInternal, nExternal;
  116.     FILE *fp;
  117.     float BalanceToSplit;
  118.  
  119.     pRoot=pRoot;
  120.     
  121.     fp = fopen( pFilename, "w" );
  122.     if( fp == NULL )
  123.         return FALSE;
  124.     
  125.     BalanceToSplit = (float)nBalancesChosen / (float)nSplitsChosen;
  126.     fprintf(fp, "Ratio of best balances to splits chosen:\t%f\n", BalanceToSplit);
  127.     
  128.     fprintf(fp, "\nRoot Line:\t\t%d\n", pLines->GetIndexFromPointer(pRoot));
  129.     
  130.     NodeInfo( pLines, &nInternal, &nExternal );
  131.     fprintf(fp, "Internal nodes:\t\t%d\n", nInternal);
  132.     fprintf(fp, "External nodes:\t\t%d\n", nExternal);
  133.  
  134.     fprintf(fp, "\nExact intersections:  %d\n", nExactIntersections);
  135.     
  136.     fprintf(fp, "\nOriginal number of Points:\t\t%d", nOriginalPoints);
  137.     fprintf(fp, "\nFinished number of Points:\t\t%d", pPoints->NumElements());
  138.     fprintf(fp, "\nRatio of finished to original:\t\t%f\n", (float)pPoints->NumElements() / (float)nOriginalPoints );
  139.  
  140.     fprintf(fp, "\nOriginal number of Lines:\t\t%d", nOriginalLines);
  141.     fprintf(fp, "\nFinished number of Lines:\t\t%d", pLines->NumElements());
  142.     fprintf(fp, "\nRatio of finished to original:\t\t%f\n", (float)pLines->NumElements() / (float)nOriginalLines );
  143.  
  144.     
  145.     // Output all the Points.
  146.     fprintf(fp, "\n\nPoints\n-------------\n");
  147.     for( i=0; i < pPoints->NumElements(); i++ )
  148.     {
  149.         pCurPoint = pPoints->GetPoint(i);
  150.         fprintf( fp, "\nPoint %d - (%d, %d)", i, pCurPoint->localX, pCurPoint->localY );
  151.     }       
  152.     
  153.     
  154.     // Output all the Lines.
  155.     fprintf( fp, "\n\n\nLines\n-------------\n" );
  156.     for( i=0; i < pLines->NumElements(); i++ )
  157.     {
  158.         pCurLine = pLines->GetLine(i);
  159.         
  160.         iPoint1 = pPoints->GetIndexFromPointer( pCurLine->pPoint1 );
  161.         iPoint2 = pPoints->GetIndexFromPointer( pCurLine->pPoint2 );
  162.         iLeft = pLines->GetIndexFromPointer( pCurLine->pLeft );
  163.         iRight = pLines->GetIndexFromPointer( pCurLine->pRight );
  164.         
  165.         fprintf( fp, "\nLine %d", i );
  166.         fprintf( fp, "\nPoints - (%d, %d),  (Left: %d, Right: %d)\n", iPoint1, iPoint2, iLeft, iRight );
  167.     }
  168.  
  169.     fclose(fp);
  170.     return TRUE;
  171. }
  172.  
  173.  
  174. void NodeInfo( CLineArray *pLineList, WORD *pNInternal, WORD *pNExternal )
  175. {
  176.     WORD i;
  177.  
  178.     *pNInternal=*pNExternal=0;
  179.  
  180.     for( i=0; i < pLineList->NumElements(); i++ )
  181.     {
  182.         if( pLineList->GetLine(i)->pLeft == NULL )
  183.             ++*pNExternal;
  184.         else
  185.             ++*pNInternal;
  186.  
  187.         if( pLineList->GetLine(i)->pRight == NULL )
  188.             ++*pNExternal;
  189.         else
  190.             ++*pNInternal;
  191.     }
  192. }
  193.  
  194.  
  195. void SkipComments(FILE *fp)
  196. {
  197.     char testChar;
  198.     
  199.     while(1)
  200.     {
  201.         testChar = (char)fgetc(fp);
  202.  
  203.         if( isdigit(testChar) )
  204.             break;
  205.     }
  206.  
  207.     fseek( fp, -1, SEEK_CUR );
  208. }
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215. //////////////////////////////////////////////////
  216. //  GRAPHICAL DISPLAY
  217. //////////////////////////////////////////////////
  218.  
  219.  
  220.  
  221.  
  222.  
  223. #ifdef DISPLAY_GRAPHICAL    
  224.  
  225. BOOL DisplayGraphicalData( CLineArray *pLines, CPointArray *pPoints )
  226. {
  227.     WORD lowestX=32767, lowestY=32767, highestX=0, highestY=0;
  228.     
  229.     WORD personX=0, personY=0;
  230.     WORD xOffset=0, yOffset=0;
  231.     WORD offsetInc = 4;
  232.     Fixed scale = FIXED_ONE;
  233.  
  234.     WORD i;
  235.     CPoint *pCurPt;
  236.  
  237.     // Find the point with the least X and make the X offset that..
  238.     for( i=0; i < pPoints->NumElements(); i++ )
  239.     {
  240.         pCurPt = pPoints->GetPoint(i);
  241.  
  242.         lowestX = LEAST(lowestX,pCurPt->localX);
  243.         lowestY = LEAST(lowestY,pCurPt->localY);
  244.     
  245.         highestX = GREATEST(highestX,pCurPt->localX);
  246.         highestY = GREATEST(highestY,pCurPt->localY);
  247.     }
  248.  
  249. #ifdef SCREEN_ON    
  250.     s_Init();
  251. #endif
  252.  
  253.     while(1)
  254.     {
  255.         if( kbhit() )
  256.         {
  257.             switch( toupper(getch()) )
  258.             {
  259.                 case 'Q':
  260. #ifdef SCREEN_ON
  261.                     s_UnInit();
  262. #endif
  263.                     return TRUE;
  264.  
  265.                 case 'W':
  266.                     personY -= offsetInc;
  267.                     break;
  268.  
  269.                 case 'A':
  270.                     personX -= offsetInc;
  271.                     break;
  272.                 
  273.                 case 'S':
  274.                     personY += offsetInc;
  275.                     break;
  276.  
  277.                 case 'D':
  278.                     personX += offsetInc;
  279.                     break;
  280.             
  281.                 case 'R':
  282.                     scale += FIXED_ONE / 30;
  283.                     
  284.                     offsetInc -= 10;
  285.                     break;
  286.  
  287.                 case 'F':
  288.                     if( scale > ((FIXED_ONE / 30) * 2) )
  289.                         scale -= FIXED_ONE / 30;
  290.                     
  291.                     offsetInc += 10;
  292.                     break;
  293.             }
  294.         }
  295.  
  296.  
  297.     xOffset = (WORD)R_UNFIX(personX*scale);
  298.     yOffset = (WORD)R_UNFIX(personY*scale);    
  299.         
  300. #ifdef SCREEN_ON
  301.     s_Clear(0);
  302. #endif
  303.  
  304.     Draw2DEnvironment( pLines, pPoints, xOffset, yOffset, scale, s_Width, s_Height );
  305.  
  306. #ifdef SCREEN_ON
  307.     s_Draw();
  308. #endif
  309.     }
  310. }
  311.  
  312.  
  313. void DrawLine( DWORD x1, DWORD y1, DWORD x2, DWORD y2 )
  314. {
  315.     WORD numPixels;
  316.     WORD i;
  317.     Fixed curX, curY, xInc, yInc;
  318.  
  319.     // Test if it's off the screen so we might not have to draw it.
  320.     if( (x1 < 0 || x1 >= s_Width) && (y1 < 0 || y1 >= s_Height) &&
  321.         (x2 < 0 || x2 >= s_Width) && (y2 < 0 || y2 >= s_Height) )
  322.         return;
  323.     
  324.     if( ABS(x2-x1) > ABS(y2-y1) )
  325.         numPixels = (WORD)ABS(x2-x1);
  326.     else
  327.         numPixels = (WORD)ABS(y2-y1);
  328.  
  329.     if( numPixels < 2 )
  330.         return;
  331.     
  332.     curX = FIX(x1);
  333.     curY = FIX(y1);
  334.  
  335.     xInc = FIX(x2-x1) / numPixels;
  336.     yInc = FIX(y2-y1) / numPixels;
  337.  
  338.     for( i=0; i < numPixels; i++ )
  339.     {
  340. #ifdef SCREEN_ON
  341.         s_SetPixel( (WORD)UNFIX(curX), (WORD)UNFIX(curY), 24 );
  342. #endif
  343.  
  344.         curX += xInc;
  345.         curY += yInc;
  346.     }
  347. }
  348.  
  349.  
  350.  
  351. #endif
  352.  
  353.  
  354.  
  355.  
  356.  
  357.  
  358. //////////////////////////////////////////////////
  359. //  DOOM FILE READING
  360. //////////////////////////////////////////////////
  361.  
  362. BOOL LoadDoomLevel( BYTE *pFilename, BYTE *pLevelName, CLineArray *pLineArray, CPointArray *pPointArray, BOOL bLoadTextures, BYTE *pTextureWadName )
  363. {
  364.     WORD nVertices, nLinedefs, nSidedefs, i;
  365.  
  366.     DoomVertex *pDoomVertices;
  367.     DoomLinedef *pDoomLinedefs, *pCurLinedef;
  368.  
  369.     DirEntry dirLevel, dirVertices, dirLinedefs, dirSidedefs;
  370.  
  371.     DWORD directoryPos, levelPos;
  372.     MFile wadFile;
  373.  
  374.     // Stuff for loading textures.
  375.     MFile textureWad;
  376.     DWORD textureDirectory;
  377.     DoomSidedef *pDoomSidedefs, *pCurSidedef;
  378.     
  379.     DoomSidedef tempSky;
  380.     
  381.     
  382.     if( wadFile.fio_OpenSource( pFilename, 'R' ) == FALSE )
  383.         return FALSE;
  384.     
  385.     // Get the position of the directory.
  386.     wadFile.fio_Seek( 8 );
  387.     wadFile.fio_Read( &directoryPos, 4 );
  388.  
  389.     levelPos = GetDirEntry( &wadFile, pLevelName, directoryPos, &dirLevel );
  390.  
  391.     // Get the directory entries for Vertices and Linedefs.
  392.     GetDirEntry( &wadFile, "VERTEXES", levelPos, &dirVertices );
  393.     GetDirEntry( &wadFile, "LINEDEFS", levelPos, &dirLinedefs );
  394.     GetDirEntry( &wadFile, "SIDEDEFS", levelPos, &dirSidedefs );
  395.  
  396.     
  397.     // Read in all the Vertices and translate them to Points.
  398.     nVertices = (WORD)(dirVertices.resLength / sizeof(DoomVertex));
  399.  
  400.     pPointArray->SetSize(nVertices);
  401.     pPointArray->AllocateElements();
  402.         
  403.     pDoomVertices = new DoomVertex[nVertices];
  404.     
  405.     wadFile.fio_Seek( dirVertices.resPos );
  406.     wadFile.fio_Read( pDoomVertices, dirVertices.resLength );
  407.  
  408.     for( i=0; i < nVertices; i++ )
  409.     {
  410.         pPointArray->GetPoint(i)->localX = (WORD)pDoomVertices[i].x;                                                 
  411.         pPointArray->GetPoint(i)->localY = (WORD)pDoomVertices[i].y;
  412.     }
  413.  
  414.     delete pDoomVertices;
  415.  
  416.     
  417.     // Read in all the Linedefs and translate them to Points.
  418.     nLinedefs = (WORD)(dirLinedefs.resLength / sizeof(DoomLinedef));
  419.  
  420.     pLineArray->SetSize(nLinedefs);
  421.     pLineArray->AllocateElements();
  422.     
  423.     // Zero-init all the Lines.
  424.     for( i=0; i < nLinedefs; i++ )
  425.         memset( pLineArray->GetLine(i), 0, sizeof(CLine) );
  426.  
  427.  
  428.     pDoomLinedefs = new DoomLinedef[nLinedefs];
  429.     memset( pDoomLinedefs, 0, sizeof(DoomLinedef)*nLinedefs );
  430.  
  431.     wadFile.fio_Seek( dirLinedefs.resPos );
  432.     wadFile.fio_Read( pDoomLinedefs, dirLinedefs.resLength );
  433.  
  434.     
  435.     
  436.     if( bLoadTextures )
  437.     {
  438.         DirEntry dirPalette;
  439.         
  440.         printf("Loading textures from %s.", pTextureWadName);
  441.         printf("\n");
  442.         
  443.         if( textureWad.fio_OpenSource( pTextureWadName, 'R' ) == FALSE )
  444.             return FALSE;
  445.     
  446.         // Get the position of the directory.
  447.         textureWad.fio_Seek( 8 );
  448.         textureWad.fio_Read( &textureDirectory, 4 );
  449.  
  450.         // Initialize Doom texture loading module.
  451.         InitDoomTex( &textureWad, textureDirectory );        
  452.         
  453.         nSidedefs = (WORD)(dirSidedefs.resLength / sizeof(DoomSidedef));
  454.  
  455.         pDoomSidedefs = new DoomSidedef[nSidedefs];
  456.         memset( pDoomSidedefs, 0, nSidedefs*sizeof(DoomSidedef) );
  457.  
  458.         // Read in the SideDefs.
  459.         wadFile.fio_Seek( dirSidedefs.resPos );
  460.         wadFile.fio_Read( pDoomSidedefs, nSidedefs * sizeof(DoomSidedef) );
  461.         
  462.         // Go through all the LineDefs and load their textures (from the SideDefs).
  463.  
  464.         for( i=0; i < nLinedefs; i++ )
  465.         {
  466.             pCurLinedef = &pDoomLinedefs[i];
  467.             
  468.             // Do the right Sidedef automatically .. all Doom Linedefs have one.
  469.             if( pCurLinedef->rightSidedef == -1 )
  470.             {
  471.                 pLineArray->GetLine(i)->idRightTex = BAD_TEXTURE_ID;
  472.             }
  473.             else
  474.             {
  475.                 pCurSidedef = &pDoomSidedefs[ pCurLinedef->rightSidedef ];
  476.                 pLineArray->GetLine(i)->idRightTex = LoadSidedefTexture( pCurSidedef, &textureWad, textureDirectory );
  477.             }
  478.             
  479.             
  480.             if( pCurLinedef->leftSidedef == -1 )
  481.             {
  482.                 pLineArray->GetLine(i)->idLeftTex = BAD_TEXTURE_ID;
  483.             }
  484.             else
  485.             {
  486.                 pCurSidedef = &pDoomSidedefs[ pCurLinedef->leftSidedef ];
  487.                 pLineArray->GetLine(i)->idLeftTex = LoadSidedefTexture( pCurSidedef, &textureWad, textureDirectory );
  488.             }            
  489.         }        
  490.     
  491.         
  492.         // The WAD with the textures is assumed to have the palette..
  493.         // Read it and the palette maps in.
  494.         if( GetDirEntry( &textureWad, "PLAYPAL", textureDirectory, &dirPalette ) != -1 )
  495.         {
  496.             textureWad.fio_Seek( dirPalette.resPos );
  497.             textureWad.fio_Read( curLevel.palette, 768 );
  498.             
  499.             for( i=0; i < 768; i++ )
  500.                 curLevel.palette[i] = curLevel.palette[i] / 4;
  501.         }
  502.         
  503. #ifndef PALETTE_MAPS
  504.         if( GetDirEntry( &textureWad, "COLORMAP", textureDirectory, &dirPalette ) != -1 )
  505.         {
  506.             textureWad.fio_Seek( dirPalette.resPos );
  507.  
  508.             nPaletteMaps = 32;
  509.             pPaletteMaps = new BYTE *[32];
  510.             
  511.             for( i=0; i < 32; i++ )
  512.             {
  513.                 pPaletteMaps[i] = new BYTE[256];
  514.                 textureWad.fio_Read( pPaletteMaps[i], 256 );
  515.             }                    
  516.         
  517.             textureWad.fio_Read( blackWhitePal, 256 );
  518.         }
  519. #endif        
  520.         
  521.         // Read in the skies too.
  522.         sprintf( tempSky.normalTex, "SKY1" );
  523.         curLevel.idSky1 = LoadSidedefTexture( &tempSky, &textureWad, textureDirectory );
  524.         
  525.         sprintf( tempSky.normalTex, "SKY2" );
  526.         curLevel.idSky2= LoadSidedefTexture( &tempSky, &textureWad, textureDirectory );
  527.         
  528.         sprintf( tempSky.normalTex, "SKY3" );
  529.         curLevel.idSky3= LoadSidedefTexture( &tempSky, &textureWad, textureDirectory );
  530.         
  531.         curLevel.idCurSky = curLevel.idSky1;
  532.  
  533.  
  534.         // UnInitialize Doom texture loading module.
  535.         UnInitDoomTex();
  536.         
  537.         textureWad.fio_CloseSource();
  538.         delete pDoomSidedefs;
  539.     }
  540.             
  541.     
  542.     for( i=0; i < nLinedefs; i++ )
  543.     {
  544.         pLineArray->GetLine(i)->pPoint1 = pPointArray->GetPoint( pDoomLinedefs[i].iFromVert );
  545.         pLineArray->GetLine(i)->pPoint2 = pPointArray->GetPoint( pDoomLinedefs[i].iToVert );
  546.     
  547.         pLineArray->GetLine(i)->wallColor = (TextureID)rand() % 255;
  548.     }
  549.  
  550.     delete pDoomLinedefs;
  551.  
  552.     
  553.     // Done .. clean up and return.
  554.     
  555.     wadFile.fio_CloseSource();
  556.     return TRUE;    
  557. }
  558.  
  559.  
  560.  
  561. DWORD GetDirEntry( MFile *pWadFile, char *pEntryName, DWORD startSearchAt, DirEntry *pEntry )
  562. {
  563.     WORD i, nEntries;
  564.  
  565.     nEntries = (pWadFile->fio_FileLength() - startSearchAt) / sizeof(DirEntry);
  566.     pWadFile->fio_Seek( startSearchAt );
  567.  
  568.     for( i=0; i < nEntries; i++ )
  569.     {
  570.         pWadFile->fio_Read( pEntry, sizeof(DirEntry) );
  571.         
  572.         if( strncmp( pEntry->resName, pEntryName, 8 ) == 0 )
  573.             return pWadFile->fio_GetPosition();
  574.     }
  575.  
  576.     return -1;
  577. }
  578.  
  579.  
  580.  
  581.